/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package helper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import model.WorkingDirectory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 *
 * @author LegACy
 */
public class Connect {

    protected static int s_Port = 10000;

    //No constructor
    protected Connect() {
    }

    protected static Socket sendRequest(int action, JSONObject request) throws IOException {
        //Create socket
        Socket Sock = new Socket(InetAddress.getLocalHost(), s_Port);

        //Create message
        String Message = "";
        Message += (char) action;
        Message += request.toString();

        //Send message
        PrintWriter Writer = new PrintWriter(Sock.getOutputStream());
        Writer.println(Message);
        Writer.flush();

        //Return the socket
        return Sock;
    }

    public static boolean login(String username, String password) throws Exception {
        //Initial
        boolean Result = false;

        try {
            //Create JSON
            JSONObject Request = new JSONObject();
            Request.put("username", username);
            Request.put("password", password);
            try {
                //Send request
                Socket Sock = sendRequest(Protocol.ACTION_LOGIN, Request);

                //Create reader
                BufferedReader Reader = new BufferedReader(new InputStreamReader(Sock.getInputStream()));

                //Read action
                int Answer = Reader.read();
                if (Answer == Protocol.ACTION_LOGIN + Protocol.RESPONSE_OFFSET) {
                    //Read response
                    JSONObject Response = new JSONObject(Reader.readLine());
                    Result = Response.getBoolean("result");

                    //If error, exception
                    if (!Result) {
                        throw new Exception(Response.getString("reason"));
                    }
                } else {
                    throw new Exception("Response error");
                }

                //Close socket
                Sock.close();
            } catch (IOException ex) {
                throw new Exception("Connection error");
            }
        } catch (JSONException ex) {
            throw new Exception("JSON Error");
        }

        //Return
        return Result;
    }

    public static int getLatest(String username) throws Exception {
        //Initial
        int Result = 0;

        try {
            //Create JSON
            JSONObject Request = new JSONObject();
            Request.put("username", username);
            try {
                //Send request
                Socket Sock = sendRequest(Protocol.ACTION_LATEST, Request);

                //Create reader
                BufferedReader Reader = new BufferedReader(new InputStreamReader(Sock.getInputStream()));

                //Read action
                int Answer = Reader.read();
                if (Answer == Protocol.ACTION_LATEST + Protocol.RESPONSE_OFFSET) {
                    //Read response
                    JSONObject Response = new JSONObject(Reader.readLine());
                    boolean ResponseResult = Response.getBoolean("result");

                    //If error, exception
                    if (ResponseResult) {
                        Result = Response.getInt("latest");
                    } else {
                        throw new Exception(Response.getString("reason"));
                    }
                } else {
                    throw new Exception("Response error");
                }

                //Close socket
                Sock.close();
            } catch (IOException ex) {
                throw new Exception("Connection error");
            }
        } catch (JSONException ex) {
            throw new Exception("JSON Error");
        }

        //Return
        return Result;
    }

    public static ArrayList<WorkingDirectory> getStructure(String username, int version) throws Exception {
        //Initial
        ArrayList<WorkingDirectory> Result = new ArrayList<WorkingDirectory>();

        try {
            //Create JSON
            JSONObject Request = new JSONObject();
            Request.put("username", username);
            Request.put("version", version);
            try {
                //Send request
                Socket Sock = sendRequest(Protocol.ACTION_STRUCTURE, Request);

                //Create reader
                BufferedReader Reader = new BufferedReader(new InputStreamReader(Sock.getInputStream()));

                //Read action
                int Answer = Reader.read();
                if (Answer == Protocol.ACTION_STRUCTURE + Protocol.RESPONSE_OFFSET) {
                    //Read response
                    JSONObject Response = new JSONObject(Reader.readLine());
                    boolean ResponseResult = Response.getBoolean("result");

                    //If error, exception
                    if (!ResponseResult) {
                        throw new Exception(Response.getString("reason"));
                    } else {
                        //Get array
                        JSONArray Directories = Response.getJSONArray("directories");
                        for (int i = 0; i < Directories.length(); i++) {
                            Result.add(new WorkingDirectory(Directories.getJSONObject(i)));
                        }
                    }
                } else {
                    throw new Exception("Response error");
                }

                //Close socket
                Sock.close();
            } catch (IOException ex) {
                throw new Exception("Connection error");
            }
        } catch (JSONException ex) {
            throw new Exception("JSON Error");
        }

        //Return
        return Result;
    }

    public static boolean sendStructure(String username, ArrayList<WorkingDirectory> directories) throws Exception {
        //Initial
        boolean Result = false;

        try {
            //Create JSON array
            JSONArray DirectoryJSON = new JSONArray();
            for (int i = 0; i < directories.size(); i++) {
                DirectoryJSON.put(directories.get(i).getJSON());
            }

            //Create json request
            JSONObject Request = new JSONObject();
            Request.put("username", username);
            Request.put("directories", DirectoryJSON);

            try {
                //Send request
                Socket Sock = sendRequest(Protocol.ACTION_STRUCTURE_UP, Request);

                //Create reader
                BufferedReader Reader = new BufferedReader(new InputStreamReader(Sock.getInputStream()));

                //Read action
                int Answer = Reader.read();
                if (Answer == Protocol.ACTION_STRUCTURE_UP + Protocol.RESPONSE_OFFSET) {
                    //Read response
                    JSONObject Response = new JSONObject(Reader.readLine());
                    Result = Response.getBoolean("result");

                    //If error, exception
                    if (!Result) {
                        throw new Exception(Response.getString("reason"));
                    }
                } else {
                    throw new Exception("Response error");
                }

                //Close socket
                Sock.close();
            } catch (IOException ex) {
                throw new Exception("Connection error");
            }
        } catch (JSONException ex) {
            throw new Exception("JSON Error");
        }

        //Return result
        return Result;
    }
}
